package magnetic.field.arduino;

import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
//import java.io.IOException;
import java.io.InputStreamReader;
//import java.io.OutputStream;

import java.io.PrintStream;
import java.util.Enumeration;



public class LocalizacaoArd implements SerialPortEventListener {
       
SerialPort serialPort;
int x;
int y;
int z,campo = 0;
int cont,cont2 = 0;
int dc1,dc2 = 0; 
int D[][] = new int [3][4];
int E[][][] = new int [3][4][3];
int t = 0;
int c = 0;
int teste[][] = new int[3][4];
FileOutputStream out; //Arquivo de saÃ­da
PrintStream p;		  //Classe para escrita de saÃ­da


		private static final String PORT_NAMES[] = { "COM4" }; // Porta Usada
        // private static final String PORT_NAMES[] = { "/dev/tty.usbmodem411" }; //
       

        private static BufferedReader input;
//        private static OutputStream output;
        private static final int TIME_OUT = 2000; // Milissegundos para bloqueio
                                                                                                // enquanto aguarda a porta
                                                                                                // abrir

        private static final int DATA_RATE = 9600; // baud rate da porta

        public void initialize() {
        	CommPortIdentifier portId = null;
            @SuppressWarnings("rawtypes")
			Enumeration portEnum = CommPortIdentifier.getPortIdentifiers();

                while (portEnum.hasMoreElements()) {
                        CommPortIdentifier currPortId = (CommPortIdentifier) portEnum
                                        .nextElement();
                        for (String portName : PORT_NAMES) {
                                if (currPortId.getName().equals(portName)) {
                                        portId = currPortId;
                                        break;
                                }
                        }
                }
                if (portId == null) {
                        System.out.println("\nPorta COM nao encontrada\n");
                        return;
                }

                try {
                        serialPort = (SerialPort) portId.open(this.getClass().getName(),
                                        TIME_OUT);

                        serialPort.setSerialPortParams(DATA_RATE, SerialPort.DATABITS_8,
                                        SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);

                        input = new BufferedReader(new InputStreamReader(
                                        serialPort.getInputStream(),"ISO-8859-1"));         // Mudança de codificação padrão UTF-8 ( -127 a 127) para
                        serialPort.addEventListener((SerialPortEventListener) this);// ISO-8859-1 (0 a 255), pois o xbee envia de 0 a 255,
                                                                                                                         
                        serialPort.notifyOnDataAvailable(true);
                } catch (Exception e) {
                        System.err.println(e.toString());
                }
        }

        /**
         * Deve ser chamado quando voc� parar de usar a porta. Evita travamento de
         * porta em plataformas Linux.
         */
        public synchronized void close() {
                if (serialPort != null) {
                        serialPort.removeEventListener();
                        serialPort.close();
                }
        }
        
        public int comparar(int pontoAtual[][]) {
    		int e[][][] = BancoMatriz();
    		int P = 10; // NÃºmero de posiÃ§Ãµes
    		int D = 4; // NÃºmero de direÃ§Ãµes
    		double distMedia[] = new double[D];
    		int m, posicao = 0, n = 0;
    		double x, y, z;
    		double soma[] = new double[P];
    		double menor = 4000;

    		for (n = 0; n < P; n++) {
    			for (m = 0; m < D; m++) {
    				x = pontoAtual[0][m] - e[n][m][0];
    				y = pontoAtual[1][m] - e[n][m][1];
    				z = pontoAtual[2][m] - e[n][m][2];

    				distMedia[m] = Math.sqrt(x * x + y * y + z * z);

    				soma[n] = soma[n] + distMedia[m];

    			}
    			if (soma[n] < menor) {
    				menor = soma[n];
    				posicao = n;
    			}
    		}

    		return posicao;
    	}
        
        public int[][][] BancoMatriz() {

    		/*
    		 * Breve explicaÃ§Ã£o do mÃ©todo: Sabendo previamente a quantidade de dados
    		 * do banco, foi criado este mÃ©todo que copia os dados do banco.txt para
    		 * um array tridimensional. Onde temos as seguintes informaÃ§Ãµes:
    		 * PosiÃ§Ãµes: 0 - 9 DireÃ§Ãµes: 0 - 3 Coordenadas magnÃ©ticas x y z
    		 */

    		FileReader fileR; // Arquivo de entrada
    		BufferedReader buff; // Classe para leitura de entrada
    		int P = 10; // NÃºmero de posiÃ§Ãµes
    		int D = 4; // NÃºmero de direÃ§Ãµes
    		int i, j; // contadores
    		int x, y, z; // coordenadas do campo magnÃ©tico

    		int E[][][] = new int[P][D][3]; // matriz para alocaÃ§Ã£o do banco de
    										// dados

    		try {
    			fileR = new FileReader("banco5");
    			buff = new BufferedReader(fileR);
    			for (i = 0; i <= (P-1); i++) {
    				@SuppressWarnings("unused")
    				int posicao = Integer.parseInt(buff.readLine());

    				for (j = 0; j <= (D-1); j++) {
    					String[] parts = buff.readLine().split(" ");
    					x = Integer.parseInt(parts[0]);
    					y = Integer.parseInt(parts[1]);
    					z = Integer.parseInt(parts[2]);
    					E[i][j][0] = x;
    					E[i][j][1] = y;
    					E[i][j][2] = z;
    				}
    			}
    			buff.close();

    		} catch (FileNotFoundException e) {
    			System.out.println("Arquivo de banco de dados nÃ£o encontrado");
    			e.printStackTrace();
    		} catch (IOException e) {
    			e.printStackTrace();
    		}

    		return E;
    	}
        
        public synchronized void serialEvent(SerialPortEvent oEvent) {

   			
        	
                if (oEvent.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
                       
                       
                        try {
                        	 
                               
                        	/*
                        	1 = X
                        	2 = Y
                        	3 = Z
                        	4 = Gauss
                        	*/

                        	   String[] parts = input.readLine().split(" ");
                        	   

                        	   if (Integer.parseInt(parts[1]) == 1 && Integer.parseInt(parts[3]) == 2 && Integer.parseInt(parts[5]) == 3) {
                        	   x = Integer.parseInt(parts[0]);
                        	   y = Integer.parseInt(parts[2]);
                        	   z = Integer.parseInt(parts[4]);
                        	   if (t > 3) {
                        		int n=   comparar(teste);
                        		System.out.println(n);
                        		System.exit(0);
                        	   }
                        	   teste[0][t] = x;
                    		   teste[1][t] = y;
                    		   teste[2][t] = z;
                    		 System.out.println("X="+x+" Y="+y+" Z="+z+" T="+t);
                        	   t++;
                        	   
                        	   }
                        	   else {
                        		   
                        		   System.out.println("Dados perdidos, favor apertar o botao novamente");
                        	   }
                        	  
                               
                               
                        } catch (IOException e) {
                                System.err.println(e.toString());

                        }
                        
                        catch (ArrayIndexOutOfBoundsException e) {

                        	
                        	System.out.println("Problema na matriz de mapeamento M");
                        }
                }
        
        }

       
        public static void main(String[] args) {
               

        	
                LocalizacaoArd app = new LocalizacaoArd();
                app.initialize();
               
                

        }
}